#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include "event.hpp"
using namespace cpp_component;

template <typename dst_type, typename src_type> dst_type pointer_cast(src_type src)
{
    return *static_cast<dst_type *>(static_cast<void *>(&src));
}

class BaseMessage
{
   public:
    BaseMessage() = default;
    virtual ~BaseMessage() = default;

    uint64_t getTimestamp() const
    {
        return this->timestamp;
    }
    void setTimestamp(uint64_t time)
    {
        this->timestamp = time;
    }
    float getScore() const
    {
        return this->score;
    }
    void setScore(float score)
    {
        this->score = score;
    }
    uint32_t getCode() const
    {
        return this->code;
    }
    void setCode(int code)
    {
        this->code = code;
    }
    const std::string &getContent() const
    {
        return this->content;
    }
    void setContent(const std::string &content)
    {
        this->content = content;
    }

   private:
    uint64_t timestamp;
    float score;
    uint32_t code;
    std::string content;
};

/**
 * 消息接收器
 */
using MessageReceiver = void(const std::shared_ptr<BaseMessage> message);
// using MessageReceiver = std::function<void(const std::shared_ptr<BaseMessage> message)>;

class IMessageAbility
{
   public:
    void registerMessage(int sendDetectId, MessageReceiver messageReceiver)
    {
        m_event.subscribe(std::to_string(sendDetectId), messageReceiver);
    }
    void registerMessage(std::string msgKey, MessageReceiver messageReceiver)
    {
        m_event.subscribe(msgKey, messageReceiver);
    }

    void unregisterMessage(int sendDetectId, MessageReceiver messageReceiver)
    {
        m_event.unsubscribe(std::to_string(sendDetectId), messageReceiver);
    }
    void unregisterMessage(std::string msgKey, MessageReceiver messageReceiver)
    {
        m_event.unsubscribe(msgKey, messageReceiver);
    }

    void sendMessage(int sendDetectId, std::shared_ptr<BaseMessage> message)
    {
        m_event.notify(std::to_string(sendDetectId), message);
    }
    void sendMessage(std::string msgKey, std::shared_ptr<BaseMessage> message)
    {
        m_event.notify(msgKey, message);
    }

   private:
    static event<MessageReceiver> m_event;
};
event<MessageReceiver> IMessageAbility::m_event = event<MessageReceiver>();

class msgreceiver
{
   public:
    static void msgreceiver101_1(const std::shared_ptr<BaseMessage> message)
    {
        std::cout << "msgreceiver101_1 " << message->getContent() << std::endl;
    }
    static void msgreceiver101_2(const std::shared_ptr<BaseMessage> message)
    {
        std::cout << "msgreceiver101_2 " << message->getContent() << std::endl;
    }
};
void msgreceiver101_4(const std::shared_ptr<BaseMessage> message)
{
    std::cout << "msgreceiver101_4 " << message->getContent() << std::endl;
}
void msgreceiver101_3(const std::shared_ptr<BaseMessage> message)
{
    std::cout << "msgreceiver101_3 " << message->getContent() << std::endl;
}
int main(int argc, char **argv)
{
    msgreceiver receiver;
    IMessageAbility msgability;
    msgability.registerMessage(101, msgreceiver::msgreceiver101_1);
    msgability.registerMessage(101, msgreceiver::msgreceiver101_2);
    msgability.registerMessage(101, msgreceiver101_3);
    msgability.registerMessage(101, msgreceiver101_4);

    auto msg = std::make_shared<BaseMessage>();
    msg->setContent("this is test from main ...");
    msgability.sendMessage(101, msg);
    msgability.unregisterMessage(101, msgreceiver::msgreceiver101_1);
    msgability.unregisterMessage(101, msgreceiver
    msgability.sendMessage(101, msg);

    // IMessageAbility msgability2;
    // msgability2.registerMessage(101, receiver.msgreceiver101_1);
    // msgability2.registerMessage(101, receiver.msgreceiver101_2);

    // msgability2.sendMessage(101, msg);

    // test1();
}
